/*-+-*****************************************************************************
 Copyright (C) 2009-2012 Oceanside Software Corporation (R)
 Dallas, Texas

 Author       : Jason T. Brower
 Purpose      : This file is part of a point-of-sale software package
                originally written for Table-Service Restaurants.
              
 Date         : July 8th of 2012
              
 History      : The application that this software file belongs to was 
                written over a 3-Year period.  The first version was written
                in C# .Net 3.5 using Windows Forms.  Being new to .Net at
                the time, I soon learned of Windows Presentation Foundation,
                liked the graphics capabilities and databinding so I
                migrated to WPF.  When the .Net 4.0 framework was released
                the application was migrated from 3.5 to 4.0. Now today,
                .Net 4.5 RC is out and I was already in process of migrating
                before I made this public.
                
Excuse Me     : Please excuse the coding style, it is not representative of
                my typical work.  During the three years I was under a very
                tight budget, constantly running out of funding and was 
                working 18 hour days hyped up on 5-Hour Energy.  The 
                design is not textbook.  It is monolythic because of
                previous issues I will not get into.  There are few comments
                in the code and the ones that are there may be incorrect.
                
What it is not: This is not the exact version that I took through PA-DSS 2.0
                nor is it the exact version running at my customer sites.
                I removed some details for security purposes including some
                encryption algorithms.  The reporting was removed because
                I was including a third party library that cannot be 
                published with this Open Source.
                
What it is    : This application has been running at high volume restaraunts
                for over a year.  It never freezes, crashes or does anything
                unexpected.  So long as it is built, installed and configured
                correctly, it is a strong system that we can all enhance.

Contact       : Please note that I can no longer work for free.  However, you
                can reach me at information@oceansidesw.com.                                                      

*********************************************************************************/
using System.Collections.Generic;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Data;
using System;
using Microsoft.Win32;

#if _LOCALDB
using Oceanside.LocalDB;
#else
using Oceanside.RemoteDB;
#endif
namespace Oceanside
{
    /// <summary>
    /// 
    /// </summary>
    public partial class PageKiosksImp : PageImpBaseClass
    {
        ComboBox comboBoxName;
        GroupBox mainGroupBox;

        const int CONST_DEFAULT_MAG_STRIPE_DELAY = 900;

        /// <summary>
        /// Constructor
        /// </summary>
        public PageKiosksImp(UIElementCollection stackControlsChild,
            DbLinkedTextBox textBoxFirstCashDrawerNumber,
            DbLinkedTextBox textBoxName,
            DbLinkedTextBox textBoxNumberCashDrawers,
            DbLinkedTextBox textBoxRevenueCenter,
            DbLinkedTextBox textBoxPrinter,
            DbLinkedTextBox textBoxMenuGroup,
            DbLinkedTextBox tbForceOrderProductGroup,
            DbLinkedTextBox tbNumberCashReceipts,
            DbLinkedTextBox tbNumberCreditReceipts,
            ComboBox comboBoxName,
            Button buttonAssignPrinter,
            Button buttonSetForcedProduct,
            Button buttonSetRevenueCenter,
            Button buttonSetMenuGroup,
            Button bSetPrinterExceptions,
            Button bSwitchMode,
            GroupBox mainGroupBox)
        {
            this.ButtonNumber = "16";
            this.ButtonLabelText = "KIOSK Configuration";
            mNewGroupIsDisabled = true;
            mDeleteGroupIsDisabled = true;
            mButtonNewEntityName = "New KIOSK";
            mButtonDeleteEntityName = "Delete KIOSK";

            this.comboBoxName = comboBoxName;
            this.mainGroupBox = mainGroupBox;
            buttonSetForcedProduct.Click += new System.Windows.RoutedEventHandler(buttonSetForcedProduct_Click);
            buttonSetRevenueCenter.Click += new System.Windows.RoutedEventHandler(buttonSetRevenueCenter_Click);
            buttonAssignPrinter.Click += new System.Windows.RoutedEventHandler(buttonAssignPrinter_Click);
            buttonSetMenuGroup.Click += new System.Windows.RoutedEventHandler(buttonSetMenuGroup_Click);
            bSetPrinterExceptions.Click += new System.Windows.RoutedEventHandler(bSetPrinterExceptions_Click);
            ///Register the controls and lock the form.
            RegisterUiElementsList(stackControlsChild);
            RegisterSaveMeGroupBoxes(null, mainGroupBox);

            ///Add all text boxes to the list.
            mTextBoxesList.Add(textBoxFirstCashDrawerNumber);
            mTextBoxesList.Add(textBoxName);
            mTextBoxesList.Add(textBoxNumberCashDrawers);
            mTextBoxesList.Add(textBoxRevenueCenter);
            mTextBoxesList.Add(textBoxMenuGroup);
            mTextBoxesList.Add(tbForceOrderProductGroup);
            mTextBoxesList.Add(tbNumberCashReceipts);
            mTextBoxesList.Add(tbNumberCreditReceipts);

            ///Add the combo boxes.
            ListofComboboxes.Add(comboBoxName);

            mListOfControlsToDisableInNonEditMode.Add(buttonAssignPrinter);
            mListOfControlsToDisableInNonEditMode.Add(buttonSetMenuGroup);
            mListOfControlsToDisableInNonEditMode.Add(buttonSetForcedProduct);
            mListOfControlsToDisableInNonEditMode.Add(buttonSetRevenueCenter);
            mListOfControlsToDisableInNonEditMode.Add(bSetPrinterExceptions);
            mListOfControlsToDisableInNonEditMode.Add(bSwitchMode);

            mEntityAddDeleteLoggingEnabled = true;
            bSwitchMode.Click += new System.Windows.RoutedEventHandler(bSwitchMode_Click);
        }

        void bSwitchMode_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Button bSwitchMode = sender as Button;

            YesNoBox mb = new YesNoBox("Oceanside POS ® will need to restart to switch modes.  Would you like to continue?");
            mb.ShowDialog();
            try
            {
                if (YesNoBox.LastResponse == UserResponse.YES)
                {
                    if (Constants.IsQuickServiceMode)
                    {
                        bSwitchMode.Content = "Switch to Quick-Serve";
                        Registry.SetValue(Constants.HKEY_PROGRAMROOT, "ISQS", 0);
                        Constants.IsQuickServiceMode = false;
                    }
                    else
                    {
                        bSwitchMode.Content = "Switch to Table-Serve";
                        Registry.SetValue(Constants.HKEY_PROGRAMROOT, "ISQS", 1);
                        Constants.IsQuickServiceMode = true;
                    }

                    System.Diagnostics.ProcessStartInfo si = new System.Diagnostics.ProcessStartInfo();
                    si.WorkingDirectory = Constants.RELAUNCH_DIRECTORY;
                    si.FileName = Constants.RELAUNCH_DIR_AND_PROGRAM;
                    System.Diagnostics.Process.Start(si);
                    Environment.Exit(0);
                }
            }
            catch (Exception ex)
            {
                UMD.ShowGuiMessageSTASafe_NOTHROW("An unexpected error has been observed.  Please try again.");
                Logging.LogException(ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bSetPrinterExceptions_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            KIOSK kiosk = comboBoxName.SelectedItem as KIOSK;
            if (kiosk != null)
            {
                AssignPrinterGroupExclusions mb = new AssignPrinterGroupExclusions(Context, kiosk);
                mb.SetMessage("Please select from the list of available product groups to prevent them from printing on " + kiosk.Name + ".");
                mb.InitChoices();
                mb.ShowDialog();
            }
        }

        void buttonSetForcedProduct_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                KIOSK fm = comboBoxName.SelectedItem as KIOSK;
                if (fm != null)
                {
                    List<string> namesList = new List<string>();
                    List<Int64?> idsList = new List<Int64?>();

                    var q = from PG in Context.PRODUCT_GROUPS where PG.IsDeleted == false select PG;
                    if (q.Any())
                    {
                        namesList.Add("Not Assigned");
                        idsList.Add(null);
                        List<PRODUCT_GROUP> printerGroups = q.ToList();
                        foreach (PRODUCT_GROUP rt in printerGroups)
                        {
                            namesList.Add(rt.Name);
                            idsList.Add(rt.Id);
                        }
                        DbObjectNameWithIdSelction sb = new DbObjectNameWithIdSelction(namesList, idsList);
                        sb.SetMessage("Select a product group to assign to this KIOSK.  If you assign a product group to this KIOSK, every time an order is placed, the system will force the user to make at least one choice from that group.  Some restaurants do this to prevent drink theft.");
                        sb.ShowDialog();

                        if (DbObjectNameWithIdSelction.LastResponse == UserResponse.ENTER)
                        {
                            fm.ForceOrderProdGroupId = DbObjectNameWithIdSelction.ChosenId;
                        }
                    }
                    else
                    {
                        UMD.ShowGuiMessageSTASafe_NOTHROW("You currently do not have any menu groups defined.");
                    }

                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
        }

        void buttonSetMenuGroup_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                KIOSK fm = comboBoxName.SelectedItem as KIOSK;
                if (fm != null)
                {
                    List<string> namesList = new List<string>();
                    List<Int64?> idsList = new List<Int64?>();

                    var q = from PG in Context.MENU_GROUPS where PG.IsDeleted == false select PG;
                    if (q.Any())
                    {
                        namesList.Add("Not Assigned");
                        idsList.Add(null);
                        List<MENU_GROUP> printerGroups = q.ToList();
                        foreach (MENU_GROUP rt in printerGroups)
                        {
                            namesList.Add(rt.Name);
                            idsList.Add(rt.Id);
                        }
                        DbObjectNameWithIdSelction sb = new DbObjectNameWithIdSelction(namesList, idsList);
                        sb.SetMessage("Select a group of menus to assign to this KIOSK.");
                        sb.ShowDialog();

                        if (DbObjectNameWithIdSelction.LastResponse == UserResponse.ENTER)
                        {
                            fm.MenuGroupId = DbObjectNameWithIdSelction.ChosenId;
                        }
                    }
                    else
                    {
                        UMD.ShowGuiMessageSTASafe_NOTHROW("You currently do not have any menu groups defined.");
                    }

                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
        }

        void buttonAssignPrinter_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                KIOSK fm = comboBoxName.SelectedItem as KIOSK;
                if (fm != null)
                {
                    List<string> namesList = new List<string>();
                    List<Int64?> idsList = new List<Int64?>();

                    var q = from PG in Context.PRINTERS where PG.IsDeleted == false && PG.IsProductGroupPrinter == false select PG;
                    if (q.Any())
                    {
                        namesList.Add("Not Assigned");
                        idsList.Add(null);
                        List<PRINTER> printerGroups = q.ToList();
                        foreach (PRINTER rt in printerGroups)
                        {
                            namesList.Add(rt.Name);
                            idsList.Add(rt.Id);
                        }
                        DbObjectNameWithIdSelction sb = new DbObjectNameWithIdSelction(namesList, idsList);
                        sb.SetMessage("Select a local printer from the list to assign to this KIOSK. Note that any printer that has the \"Is Product Group Printer\" option set cannot be a local printer.");
                        sb.ShowDialog();

                        if (DbObjectNameWithIdSelction.LastResponse == UserResponse.ENTER)
                        {
                            fm.LocalPrinterId = DbObjectNameWithIdSelction.ChosenId;
                        }
                    }
                    else
                    {
                        UMD.ShowGuiMessageSTASafe_NOTHROW("You currently do not have any local printers defined.  Note that any printer that has the \"Is Product Group Printer\" option set cannot be a local printer.");
                    }

                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
        }

        void buttonSetRevenueCenter_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                KIOSK kiosk = comboBoxName.SelectedItem as KIOSK;
                if (kiosk != null)
                {
                    List<string> namesList = new List<string>();
                    List<Int64> idsList = new List<Int64>();

                    var q = from RC in Context.REVENUE_CENTERS where RC.IsDeleted == false select RC;
                    if (q.Any())
                    {
                        List<REVENUE_CENTER> revTypes = q.ToList();
                        foreach (REVENUE_CENTER rc in revTypes)
                        {
                            namesList.Add(rc.Name);
                            idsList.Add(rc.Id);
                        }
                    }
                    RevenueCenterSelectionListBox sb = new RevenueCenterSelectionListBox(namesList, idsList, Context);
                    sb.SetMessage("Select a revenue center from the list, or create a new revenue center.  Examples of revenue centers are the Patio, Bar and Dining Room.");
                    sb.ShowDialog();
                    if (RevenueCenterSelectionListBox.LastResponse == UserResponse.ENTER)
                    {
                        kiosk.RevenueCenterId = RevenueCenterSelectionListBox.ChosenId;
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        override public List<EntityObject> GetEntityObjectSet()
        {
            try
            {
                var q = from KIOSK in Context.KIOSKS.Include("AUTO_GRATUITYS") where KIOSK.IsDeleted == false select KIOSK;
                if (q.Any())
                {
                    return new List<EntityObject>(q.ToList());
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        override public void ResetFocus()
        {
            base.ResetFocus();
            mainGroupBox.DataContext = null;
            mainGroupBox.DataContext = Context;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override EntityObject GetSelectedEntityObject()
        {
            KIOSK selected = comboBoxName.SelectedItem as KIOSK;
            return selected;
        }

        /// <summary>
        /// 
        /// </summary>
        public override void MarkEntityDeleted()
        {
            KIOSK selected = comboBoxName.SelectedItem as KIOSK;
            if (selected != null)
            {
                selected.IsDeleted = true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public override void UpdateUsersEntitySource()
        {
            try
            {
                ///Create the query object.
                var query = from KIOSK in Context.KIOSKS
                            where KIOSK.IsDeleted == false
                            orderby KIOSK.Name
                            select KIOSK;

                if (query.Any())
                {
                    comboBoxName.ItemsSource = query;
                    comboBoxName.SelectedItem = query.First();
                }
                else
                {
                    comboBoxName.ItemsSource = null;
                }
            }
            catch (Exception e)
            {
                Logging.LogException(e);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        override public void CancelNewEntityWasClicked()
        {
            try
            {
                UpdateUsersEntitySource();

            }
            catch (Exception e)
            {
                Logging.LogException(e);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override EntityObject AddNewEntityObject()
        {
            KIOSK newObject = null;
            try
            {
                var q = from KIOSK in Context.KIOSKS where KIOSK.Name.Equals("Not Assigned") select KIOSK;

                if (q.Count() == 0)
                {
                    newObject = new KIOSK();
                    newObject.Name = "Not Assigned";
                    newObject.MagStripeDelay = CONST_DEFAULT_MAG_STRIPE_DELAY;
                    newObject.FirstCashDrawerNumber = 0;
                    newObject.NumberOfCashDrawers = 0;
                    newObject.NumberCreditReceipts = 2;
                    newObject.NumberCashReceipts = 1;
                    newObject.NumberGiftReceipts = 1;
                    newObject.PrintCreditReceiptOnPay = true;
                    newObject.PrintGiftReceiptOnPay = true;
                    newObject.PrintCashReceiptOnPay = true;
                    newObject.IsDeleted = false;
                    Context.KIOSKS.AddObject(newObject);
                }
                else
                {
                    newObject = q.First();
                    newObject.IsDeleted = false;
                }
            }
            catch (Exception e)
            {
                Logging.LogException(e);
            }
            return newObject;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override ComboBox GetEntityComboBox()
        {
            return comboBoxName;
        }
    }
}
